{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import all necessary libraries\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn import preprocessing\n",
    "import tensorflow\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import LSTM, Dense, Dropout\n",
    "from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau\n",
    "from tensorflow.keras.optimizers import Adam\n",
    "import time\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.random.seed(7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>GDP</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>DATE</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1947-01-01</th>\n",
       "      <td>243.164</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1947-04-01</th>\n",
       "      <td>245.968</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1947-07-01</th>\n",
       "      <td>249.585</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1947-10-01</th>\n",
       "      <td>259.745</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1948-01-01</th>\n",
       "      <td>265.742</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                GDP\n",
       "DATE               \n",
       "1947-01-01  243.164\n",
       "1947-04-01  245.968\n",
       "1947-07-01  249.585\n",
       "1947-10-01  259.745\n",
       "1948-01-01  265.742"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#load gdp data\n",
    "df = pd.read_csv('GDP.csv', index_col=0)\n",
    "\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "#set look-back to 12 and forecast out to 2 \n",
    "LOOK_BACK = 12\n",
    "FORECAST_OUT = 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# get rid of any nan values just in case\n",
    "df.fillna(method='ffill', inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>GDP</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>DATE</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1947-01-01</th>\n",
       "      <td>243.164</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1947-04-01</th>\n",
       "      <td>245.968</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1947-07-01</th>\n",
       "      <td>249.585</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1947-10-01</th>\n",
       "      <td>259.745</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1948-01-01</th>\n",
       "      <td>265.742</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                GDP\n",
       "DATE               \n",
       "1947-01-01  243.164\n",
       "1947-04-01  245.968\n",
       "1947-07-01  249.585\n",
       "1947-10-01  259.745\n",
       "1948-01-01  265.742"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>GDP</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>291.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>6143.537649</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>6239.150629</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>243.164000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>723.990500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>3578.848000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>10597.058000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>21542.104000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                GDP\n",
       "count    291.000000\n",
       "mean    6143.537649\n",
       "std     6239.150629\n",
       "min      243.164000\n",
       "25%      723.990500\n",
       "50%     3578.848000\n",
       "75%    10597.058000\n",
       "max    21542.104000"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# see statistics of the dataset\n",
    "df.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(232, 1)\n",
      "(59, 1)\n",
      "(232, 1)\n",
      "(59, 1)\n"
     ]
    }
   ],
   "source": [
    "# set train-test-split percent to 80%\n",
    "TRAIN_PCT = 0.80\n",
    "\n",
    "#split gdp data into train and validation(test) data\n",
    "train_data = df[:int(TRAIN_PCT * df.shape[0])]\n",
    "valid_data = df[int(TRAIN_PCT * df.shape[0]):]\n",
    "\n",
    "print(train_data.shape)\n",
    "print(valid_data.shape)\n",
    "\n",
    "# normalize (scale) gdp date between 0 and 1\n",
    "gdp_scaler = preprocessing.MinMaxScaler()\n",
    "\n",
    "scaled_train_gdp = gdp_scaler.fit_transform(train_data[['GDP']].values)\n",
    "scaled_valid_gdp = gdp_scaler.transform(valid_data[['GDP']].values)\n",
    "\n",
    "\n",
    "scaled_train_data = pd.DataFrame(\n",
    "    np.concatenate([scaled_train_gdp], axis=1), \n",
    "    columns=['GDP']\n",
    "    )\n",
    "\n",
    "scaled_valid_data = pd.DataFrame(\n",
    "    np.concatenate([scaled_valid_gdp], axis=1), \n",
    "    columns=['GDP']\n",
    "    )\n",
    "\n",
    "#clean any nan values\n",
    "scaled_train_data.dropna(inplace=True)\n",
    "scaled_valid_data.dropna(inplace=True)\n",
    "\n",
    "print(scaled_train_data.shape)\n",
    "print(scaled_valid_data.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# function for processing the data to make it compatible with LSTM model\n",
    "\n",
    "def processData(data, lb, fc_out):\n",
    "\n",
    "    if isinstance(data, pd.DataFrame):\n",
    "        data = data.values\n",
    "\n",
    "    X, y = [], []\n",
    "\n",
    "    for i in range(len(data)-lb-1):\n",
    "\n",
    "        if data.shape[1] > 1:\n",
    "            X.append(data[i:(i+lb), :-1])\n",
    "\n",
    "        elif data.shape[1] == 1:\n",
    "            X.append(data[i:(i+lb), 0])\n",
    "\n",
    "        y.append(data[(i+lb):(i+lb+fc_out), 0])\n",
    "\n",
    "    X, y = np.array(X), np.array(y)\n",
    "\n",
    "    if data.shape[1] == 1:\n",
    "        X = X.reshape((X.shape[0], X.shape[1], 1))\n",
    "\n",
    "    return X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "train_X: (217, 12, 1)\n",
      "train_y: (217, 2)\n",
      "valid_X: (44, 12, 1)\n",
      "valid_y: (44, 2)\n"
     ]
    }
   ],
   "source": [
    "# get processed train and test data\n",
    "train_X, train_y = processData(scaled_train_data, LOOK_BACK, FORECAST_OUT)\n",
    "valid_X, valid_y = processData(scaled_valid_data, LOOK_BACK, FORECAST_OUT)\n",
    "\n",
    "print(f\"train_X: {train_X.shape}\\ntrain_y: {train_y.shape}\\nvalid_X: {valid_X.shape}\\nvalid_y: {valid_y.shape}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.00306729, 0.00384543],\n",
       "       [0.00384543, 0.00529258],\n",
       "       [0.00529258, 0.0062529 ],\n",
       "       [0.0062529 , 0.00756039],\n",
       "       [0.00756039, 0.00821922],\n",
       "       [0.00821922, 0.00881332],\n",
       "       [0.00881332, 0.00920365],\n",
       "       [0.00920365, 0.00950025],\n",
       "       [0.00950025, 0.00959879],\n",
       "       [0.00959879, 0.01014206],\n",
       "       [0.01014206, 0.0112098 ],\n",
       "       [0.0112098 , 0.01179354],\n",
       "       [0.01179354, 0.01210048],\n",
       "       [0.01210048, 0.01205341],\n",
       "       [0.01205341, 0.01162985],\n",
       "       [0.01162985, 0.01157895],\n",
       "       [0.01157895, 0.01164215],\n",
       "       [0.01164215, 0.01203916],\n",
       "       [0.01203916, 0.01275077],\n",
       "       [0.01275077, 0.01383707],\n",
       "       [0.01383707, 0.01452596],\n",
       "       [0.01452596, 0.01523357],\n",
       "       [0.01523357, 0.01579313],\n",
       "       [0.01579313, 0.01600927],\n",
       "       [0.01600927, 0.0165194 ],\n",
       "       [0.0165194 , 0.01694133],\n",
       "       [0.01694133, 0.01769642],\n",
       "       [0.01769642, 0.0184551 ],\n",
       "       [0.0184551 , 0.01863801],\n",
       "       [0.01863801, 0.01924595],\n",
       "       [0.01924595, 0.01886921],\n",
       "       [0.01886921, 0.01827276],\n",
       "       [0.01827276, 0.01863418],\n",
       "       [0.01863418, 0.01976316],\n",
       "       [0.01976316, 0.02088   ],\n",
       "       [0.02088   , 0.0217575 ],\n",
       "       [0.0217575 , 0.02276106],\n",
       "       [0.02276106, 0.02295496],\n",
       "       [0.02295496, 0.02324537],\n",
       "       [0.02324537, 0.02438942],\n",
       "       [0.02438942, 0.02426172],\n",
       "       [0.02426172, 0.02463015],\n",
       "       [0.02463015, 0.02418981],\n",
       "       [0.02418981, 0.02458242],\n",
       "       [0.02458242, 0.02543972],\n",
       "       [0.02543972, 0.02642667],\n",
       "       [0.02642667, 0.02748113],\n",
       "       [0.02748113, 0.02857248],\n",
       "       [0.02857248, 0.02908986],\n",
       "       [0.02908986, 0.0297952 ],\n",
       "       [0.0297952 , 0.03006012],\n",
       "       [0.03006012, 0.03082498],\n",
       "       [0.03082498, 0.031483  ],\n",
       "       [0.031483  , 0.03267949],\n",
       "       [0.03267949, 0.03345266],\n",
       "       [0.03345266, 0.03474623],\n",
       "       [0.03474623, 0.03546712],\n",
       "       [0.03546712, 0.03655489],\n",
       "       [0.03655489, 0.03698553],\n",
       "       [0.03698553, 0.03865265],\n",
       "       [0.03865265, 0.03966257],\n",
       "       [0.03966257, 0.04122064],\n",
       "       [0.04122064, 0.04305577],\n",
       "       [0.04305577, 0.04500027],\n",
       "       [0.04500027, 0.04575332],\n",
       "       [0.04575332, 0.04694696],\n",
       "       [0.04694696, 0.04805973],\n",
       "       [0.04805973, 0.0489448 ],\n",
       "       [0.0489448 , 0.04933676],\n",
       "       [0.04933676, 0.05066013],\n",
       "       [0.05066013, 0.05197992],\n",
       "       [0.05197992, 0.05425595],\n",
       "       [0.05425595, 0.0562884 ],\n",
       "       [0.0562884 , 0.05763059],\n",
       "       [0.05763059, 0.05903173],\n",
       "       [0.05903173, 0.06109268],\n",
       "       [0.06109268, 0.06236988],\n",
       "       [0.06236988, 0.06407487],\n",
       "       [0.06407487, 0.06474193],\n",
       "       [0.06474193, 0.06580494],\n",
       "       [0.06580494, 0.0671222 ],\n",
       "       [0.0671222 , 0.06864379],\n",
       "       [0.06864379, 0.06885137],\n",
       "       [0.06885137, 0.07264216],\n",
       "       [0.07264216, 0.07436172],\n",
       "       [0.07436172, 0.07610482],\n",
       "       [0.07610482, 0.07713274],\n",
       "       [0.07713274, 0.08041567],\n",
       "       [0.08041567, 0.0833279 ],\n",
       "       [0.0833279 , 0.08529846],\n",
       "       [0.08529846, 0.08842063],\n",
       "       [0.08842063, 0.09237738],\n",
       "       [0.09237738, 0.09534149],\n",
       "       [0.09534149, 0.09696626],\n",
       "       [0.09696626, 0.10042339],\n",
       "       [0.10042339, 0.10163845],\n",
       "       [0.10163845, 0.10480207],\n",
       "       [0.10480207, 0.10724277],\n",
       "       [0.10724277, 0.11047204],\n",
       "       [0.11047204, 0.11181064],\n",
       "       [0.11181064, 0.11472099],\n",
       "       [0.11472099, 0.11944172],\n",
       "       [0.11944172, 0.12367739],\n",
       "       [0.12367739, 0.12845423],\n",
       "       [0.12845423, 0.13104763],\n",
       "       [0.13104763, 0.13383493],\n",
       "       [0.13383493, 0.13772075],\n",
       "       [0.13772075, 0.14214895],\n",
       "       [0.14214895, 0.14762656],\n",
       "       [0.14762656, 0.15272165],\n",
       "       [0.15272165, 0.15645127],\n",
       "       [0.15645127, 0.15958583],\n",
       "       [0.15958583, 0.170081  ],\n",
       "       [0.170081  , 0.17524581],\n",
       "       [0.17524581, 0.18191526],\n",
       "       [0.18191526, 0.18595956],\n",
       "       [0.18595956, 0.19122348],\n",
       "       [0.19122348, 0.19743867],\n",
       "       [0.19743867, 0.20202511],\n",
       "       [0.20202511, 0.20739668],\n",
       "       [0.20739668, 0.20800828],\n",
       "       [0.20800828, 0.2128238 ],\n",
       "       [0.2128238 , 0.22333535],\n",
       "       [0.22333535, 0.23462666],\n",
       "       [0.23462666, 0.23774786],\n",
       "       [0.23774786, 0.24573507],\n",
       "       [0.24573507, 0.24738085],\n",
       "       [0.24738085, 0.2468502 ],\n",
       "       [0.2468502 , 0.25154673],\n",
       "       [0.25154673, 0.25434413],\n",
       "       [0.25434413, 0.25729537],\n",
       "       [0.25729537, 0.26306542],\n",
       "       [0.26306542, 0.27165185],\n",
       "       [0.27165185, 0.280637  ],\n",
       "       [0.280637  , 0.28923092],\n",
       "       [0.28923092, 0.29846177],\n",
       "       [0.29846177, 0.30673157],\n",
       "       [0.30673157, 0.31281084],\n",
       "       [0.31281084, 0.3180474 ],\n",
       "       [0.3180474 , 0.32469413],\n",
       "       [0.32469413, 0.32996473],\n",
       "       [0.32996473, 0.33744775],\n",
       "       [0.33744775, 0.34211587],\n",
       "       [0.34211587, 0.34731162],\n",
       "       [0.34731162, 0.35036115],\n",
       "       [0.35036115, 0.35543711],\n",
       "       [0.35543711, 0.35950559],\n",
       "       [0.35950559, 0.36476071],\n",
       "       [0.36476071, 0.37160184],\n",
       "       [0.37160184, 0.37798618],\n",
       "       [0.37798618, 0.38803882],\n",
       "       [0.38803882, 0.39336309],\n",
       "       [0.39336309, 0.40286398],\n",
       "       [0.40286398, 0.41042136],\n",
       "       [0.41042136, 0.41992307],\n",
       "       [0.41992307, 0.42902329],\n",
       "       [0.42902329, 0.43726565],\n",
       "       [0.43726565, 0.44401703],\n",
       "       [0.44401703, 0.44824139],\n",
       "       [0.44824139, 0.45845894],\n",
       "       [0.45845894, 0.46557069],\n",
       "       [0.46557069, 0.47005695],\n",
       "       [0.47005695, 0.46921138],\n",
       "       [0.46921138, 0.47169076],\n",
       "       [0.47169076, 0.47915734],\n",
       "       [0.47915734, 0.48559706],\n",
       "       [0.48559706, 0.49036958],\n",
       "       [0.49036958, 0.49839628],\n",
       "       [0.49839628, 0.50716399],\n",
       "       [0.50716399, 0.51497211],\n",
       "       [0.51497211, 0.52426925],\n",
       "       [0.52426925, 0.52823171],\n",
       "       [0.52823171, 0.53470441],\n",
       "       [0.53470441, 0.54066234],\n",
       "       [0.54066234, 0.55138286],\n",
       "       [0.55138286, 0.55968254],\n",
       "       [0.55968254, 0.57037366],\n",
       "       [0.57037366, 0.57722619],\n",
       "       [0.57722619, 0.58734186],\n",
       "       [0.58734186, 0.5927983 ],\n",
       "       [0.5927983 , 0.59757937],\n",
       "       [0.59757937, 0.60589648],\n",
       "       [0.60589648, 0.61318201],\n",
       "       [0.61318201, 0.62099047],\n",
       "       [0.62099047, 0.63437661],\n",
       "       [0.63437661, 0.64240381],\n",
       "       [0.64240381, 0.65285745],\n",
       "       [0.65285745, 0.66123613],\n",
       "       [0.66123613, 0.67395432],\n",
       "       [0.67395432, 0.68568125],\n",
       "       [0.68568125, 0.69407622],\n",
       "       [0.69407622, 0.70226669],\n",
       "       [0.70226669, 0.71067265],\n",
       "       [0.71067265, 0.72300222],\n",
       "       [0.72300222, 0.73708239],\n",
       "       [0.73708239, 0.74712151],\n",
       "       [0.74712151, 0.75582627],\n",
       "       [0.75582627, 0.76866938],\n",
       "       [0.76866938, 0.78638397],\n",
       "       [0.78638397, 0.7948111 ],\n",
       "       [0.7948111 , 0.81474895],\n",
       "       [0.81474895, 0.82062438],\n",
       "       [0.82062438, 0.83033181],\n",
       "       [0.83033181, 0.83308882],\n",
       "       [0.83308882, 0.84326394],\n",
       "       [0.84326394, 0.8431395 ],\n",
       "       [0.8431395 , 0.84835154],\n",
       "       [0.84835154, 0.85882921],\n",
       "       [0.85882921, 0.86731954],\n",
       "       [0.86731954, 0.87536921],\n",
       "       [0.87536921, 0.88183637],\n",
       "       [0.88183637, 0.89096103],\n",
       "       [0.89096103, 0.90149652],\n",
       "       [0.90149652, 0.92221853],\n",
       "       [0.92221853, 0.93866488],\n",
       "       [0.93866488, 0.9509534 ],\n",
       "       [0.9509534 , 0.96633038]])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(train_y)\n",
    "train_y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[0.00000000e+00],\n",
       "        [2.28352504e-04],\n",
       "        [5.22914205e-04],\n",
       "        ...,\n",
       "        [2.29549645e-03],\n",
       "        [2.42074828e-03],\n",
       "        [2.23653524e-03]],\n",
       "\n",
       "       [[2.28352504e-04],\n",
       "        [5.22914205e-04],\n",
       "        [1.35032556e-03],\n",
       "        ...,\n",
       "        [2.42074828e-03],\n",
       "        [2.23653524e-03],\n",
       "        [3.06728556e-03]],\n",
       "\n",
       "       [[5.22914205e-04],\n",
       "        [1.35032556e-03],\n",
       "        [1.83871000e-03],\n",
       "        ...,\n",
       "        [2.23653524e-03],\n",
       "        [3.06728556e-03],\n",
       "        [3.84542685e-03]],\n",
       "\n",
       "       ...,\n",
       "\n",
       "       [[8.20624384e-01],\n",
       "        [8.30331809e-01],\n",
       "        [8.33088815e-01],\n",
       "        ...,\n",
       "        [8.81836374e-01],\n",
       "        [8.90961028e-01],\n",
       "        [9.01496515e-01]],\n",
       "\n",
       "       [[8.30331809e-01],\n",
       "        [8.33088815e-01],\n",
       "        [8.43263939e-01],\n",
       "        ...,\n",
       "        [8.90961028e-01],\n",
       "        [9.01496515e-01],\n",
       "        [9.22218528e-01]],\n",
       "\n",
       "       [[8.33088815e-01],\n",
       "        [8.43263939e-01],\n",
       "        [8.43139502e-01],\n",
       "        ...,\n",
       "        [9.01496515e-01],\n",
       "        [9.22218528e-01],\n",
       "        [9.38664876e-01]]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From C:\\Miniconda3\\lib\\site-packages\\tensorflow\\python\\ops\\init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Call initializer instance with the dtype argument instead of passing it to the constructor\n"
     ]
    }
   ],
   "source": [
    "#create LSTM model\n",
    "model = Sequential()\n",
    "\n",
    "model.add(LSTM(512, input_shape=(train_X.shape[1:]), activation='relu', return_sequences=False))\n",
    "model.add(Dropout(0.2))\n",
    "\n",
    "model.add(Dense(FORECAST_OUT))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 217 samples, validate on 44 samples\n",
      "WARNING:tensorflow:From C:\\Miniconda3\\lib\\site-packages\\tensorflow\\python\\ops\\math_grad.py:1250: add_dispatch_support.<locals>.wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use tf.where in 2.0, which has the same broadcast rule as np.where\n",
      "Epoch 1/100\n",
      "217/217 [==============================] - 3s 12ms/sample - loss: 0.0756 - mean_squared_error: 0.0756 - acc: 0.5346 - val_loss: 0.6840 - val_mean_squared_error: 0.6840 - val_acc: 0.9318\n",
      "Epoch 2/100\n",
      "217/217 [==============================] - 1s 7ms/sample - loss: 0.0718 - mean_squared_error: 0.0718 - acc: 0.6083 - val_loss: 0.9632 - val_mean_squared_error: 0.9632 - val_acc: 0.0682\n",
      "Epoch 3/100\n",
      "217/217 [==============================] - 1s 7ms/sample - loss: 0.0499 - mean_squared_error: 0.0499 - acc: 0.0461 - val_loss: 0.0940 - val_mean_squared_error: 0.0940 - val_acc: 0.0682\n",
      "Epoch 4/100\n",
      "217/217 [==============================] - 1s 7ms/sample - loss: 0.0143 - mean_squared_error: 0.0143 - acc: 0.4055 - val_loss: 0.0395 - val_mean_squared_error: 0.0395 - val_acc: 0.9318\n",
      "Epoch 5/100\n",
      "217/217 [==============================] - 1s 7ms/sample - loss: 0.0043 - mean_squared_error: 0.0043 - acc: 0.7143 - val_loss: 0.0948 - val_mean_squared_error: 0.0948 - val_acc: 0.0682\n",
      "Epoch 6/100\n",
      "217/217 [==============================] - 2s 8ms/sample - loss: 0.0024 - mean_squared_error: 0.0024 - acc: 0.2350 - val_loss: 0.1034 - val_mean_squared_error: 0.1034 - val_acc: 0.0682\n",
      "Epoch 7/100\n",
      "217/217 [==============================] - 2s 8ms/sample - loss: 0.0013 - mean_squared_error: 0.0013 - acc: 0.5023 - val_loss: 0.0046 - val_mean_squared_error: 0.0046 - val_acc: 0.9318\n",
      "Epoch 8/100\n",
      "217/217 [==============================] - 1s 7ms/sample - loss: 9.1691e-04 - mean_squared_error: 9.1691e-04 - acc: 0.7696 - val_loss: 0.0011 - val_mean_squared_error: 0.0011 - val_acc: 0.9318\n",
      "Epoch 9/100\n",
      "217/217 [==============================] - 1s 7ms/sample - loss: 7.5021e-04 - mean_squared_error: 7.5021e-04 - acc: 0.5668 - val_loss: 0.0012 - val_mean_squared_error: 0.0012 - val_acc: 0.9318\n",
      "Epoch 10/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 6.7316e-04 - mean_squared_error: 6.7316e-04 - acc: 0.5991 - val_loss: 0.0084 - val_mean_squared_error: 0.0084 - val_acc: 0.9318\n",
      "Epoch 11/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 6.8573e-04 - mean_squared_error: 6.8573e-04 - acc: 0.5760 - val_loss: 0.0016 - val_mean_squared_error: 0.0016 - val_acc: 0.9318\n",
      "Epoch 12/100\n",
      "217/217 [==============================] - 2s 8ms/sample - loss: 9.4664e-04 - mean_squared_error: 9.4664e-04 - acc: 0.4977 - val_loss: 0.0053 - val_mean_squared_error: 0.0053 - val_acc: 0.9318\n",
      "Epoch 13/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 9.1925e-04 - mean_squared_error: 9.1925e-04 - acc: 0.5161 - val_loss: 0.0042 - val_mean_squared_error: 0.0042 - val_acc: 0.9318\n",
      "Epoch 14/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 0.0010 - mean_squared_error: 0.0010 - acc: 0.5622 - val_loss: 0.0022 - val_mean_squared_error: 0.0022 - val_acc: 0.9318\n",
      "Epoch 15/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 7.2481e-04 - mean_squared_error: 7.2481e-04 - acc: 0.5161 - val_loss: 0.0017 - val_mean_squared_error: 0.0017 - val_acc: 0.9318\n",
      "Epoch 16/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.7954e-04 - mean_squared_error: 5.7954e-04 - acc: 0.5899 - val_loss: 9.2058e-04 - val_mean_squared_error: 9.2058e-04 - val_acc: 0.9318\n",
      "Epoch 17/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 6.6001e-04 - mean_squared_error: 6.6001e-04 - acc: 0.6313 - val_loss: 0.0014 - val_mean_squared_error: 0.0014 - val_acc: 0.9318\n",
      "Epoch 18/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.9741e-04 - mean_squared_error: 5.9741e-04 - acc: 0.6912 - val_loss: 0.0015 - val_mean_squared_error: 0.0015 - val_acc: 0.9318\n",
      "Epoch 19/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.1616e-04 - mean_squared_error: 5.1616e-04 - acc: 0.6452 - val_loss: 0.0019 - val_mean_squared_error: 0.0019 - val_acc: 0.9318\n",
      "Epoch 20/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 6.2996e-04 - mean_squared_error: 6.2996e-04 - acc: 0.5392 - val_loss: 0.0027 - val_mean_squared_error: 0.0027 - val_acc: 0.9318\n",
      "Epoch 21/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 7.0065e-04 - mean_squared_error: 7.0065e-04 - acc: 0.5668 - val_loss: 0.0010 - val_mean_squared_error: 0.0010 - val_acc: 0.9318\n",
      "Epoch 22/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.6192e-04 - mean_squared_error: 5.6192e-04 - acc: 0.5530 - val_loss: 9.4077e-04 - val_mean_squared_error: 9.4077e-04 - val_acc: 0.9318\n",
      "Epoch 23/100\n",
      "217/217 [==============================] - 2s 8ms/sample - loss: 4.8910e-04 - mean_squared_error: 4.8910e-04 - acc: 0.5853 - val_loss: 9.1290e-04 - val_mean_squared_error: 9.1290e-04 - val_acc: 0.9318\n",
      "Epoch 24/100\n",
      "217/217 [==============================] - 1s 7ms/sample - loss: 6.2327e-04 - mean_squared_error: 6.2327e-04 - acc: 0.5530 - val_loss: 9.5277e-04 - val_mean_squared_error: 9.5277e-04 - val_acc: 0.2727\n",
      "Epoch 25/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.8773e-04 - mean_squared_error: 5.8773e-04 - acc: 0.4747 - val_loss: 0.0012 - val_mean_squared_error: 0.0012 - val_acc: 0.9318\n",
      "Epoch 26/100\n",
      "217/217 [==============================] - 2s 8ms/sample - loss: 5.8122e-04 - mean_squared_error: 5.8122e-04 - acc: 0.6359 - val_loss: 0.0015 - val_mean_squared_error: 0.0015 - val_acc: 0.9318\n",
      "Epoch 27/100\n",
      "217/217 [==============================] - 2s 8ms/sample - loss: 5.5668e-04 - mean_squared_error: 5.5668e-04 - acc: 0.6544 - val_loss: 0.0011 - val_mean_squared_error: 0.0011 - val_acc: 0.9318\n",
      "Epoch 28/100\n",
      "217/217 [==============================] - 2s 8ms/sample - loss: 5.8139e-04 - mean_squared_error: 5.8139e-04 - acc: 0.6359 - val_loss: 0.0017 - val_mean_squared_error: 0.0017 - val_acc: 0.9318\n",
      "Epoch 29/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.7294e-04 - mean_squared_error: 5.7294e-04 - acc: 0.5668 - val_loss: 0.0013 - val_mean_squared_error: 0.0013 - val_acc: 0.9318\n",
      "Epoch 30/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 6.6472e-04 - mean_squared_error: 6.6472e-04 - acc: 0.5438 - val_loss: 0.0019 - val_mean_squared_error: 0.0019 - val_acc: 0.0909\n",
      "Epoch 31/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 6.9680e-04 - mean_squared_error: 6.9680e-04 - acc: 0.5300 - val_loss: 0.0010 - val_mean_squared_error: 0.0010 - val_acc: 0.9318\n",
      "Epoch 32/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 4.6997e-04 - mean_squared_error: 4.6997e-04 - acc: 0.6359 - val_loss: 9.4256e-04 - val_mean_squared_error: 9.4256e-04 - val_acc: 0.9318\n",
      "Epoch 33/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 6.0255e-04 - mean_squared_error: 6.0255e-04 - acc: 0.6728 - val_loss: 0.0012 - val_mean_squared_error: 0.0012 - val_acc: 0.9318\n",
      "Epoch 34/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.3781e-04 - mean_squared_error: 5.3781e-04 - acc: 0.6313 - val_loss: 9.2545e-04 - val_mean_squared_error: 9.2545e-04 - val_acc: 0.9318\n",
      "Epoch 35/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 4.8240e-04 - mean_squared_error: 4.8240e-04 - acc: 0.5622 - val_loss: 0.0034 - val_mean_squared_error: 0.0034 - val_acc: 0.9318\n",
      "Epoch 36/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.0179e-04 - mean_squared_error: 5.0179e-04 - acc: 0.5484 - val_loss: 0.0014 - val_mean_squared_error: 0.0014 - val_acc: 0.9318\n",
      "Epoch 37/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.9141e-04 - mean_squared_error: 5.9141e-04 - acc: 0.6267 - val_loss: 0.0011 - val_mean_squared_error: 0.0011 - val_acc: 0.9318\n",
      "Epoch 38/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.8379e-04 - mean_squared_error: 5.8379e-04 - acc: 0.6267 - val_loss: 0.0027 - val_mean_squared_error: 0.0027 - val_acc: 0.9318\n",
      "Epoch 39/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 7.2761e-04 - mean_squared_error: 7.2761e-04 - acc: 0.6452 - val_loss: 9.7082e-04 - val_mean_squared_error: 9.7082e-04 - val_acc: 0.9318\n",
      "Epoch 40/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.7440e-04 - mean_squared_error: 5.7440e-04 - acc: 0.6544 - val_loss: 0.0055 - val_mean_squared_error: 0.0055 - val_acc: 0.9318\n",
      "Epoch 41/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 5.3175e-04 - mean_squared_error: 5.3175e-04 - acc: 0.6083 - val_loss: 0.0015 - val_mean_squared_error: 0.0015 - val_acc: 0.9318\n",
      "Epoch 42/100\n",
      "217/217 [==============================] - 2s 7ms/sample - loss: 6.5174e-04 - mean_squared_error: 6.5174e-04 - acc: 0.6221 - val_loss: 0.0014 - val_mean_squared_error: 0.0014 - val_acc: 0.9318\n",
      "Epoch 00042: early stopping\n"
     ]
    }
   ],
   "source": [
    "# use ADAM as model optimizer and set learning rate to 0.003\n",
    "opt = Adam(lr=0.003)\n",
    "\n",
    "model.compile(loss=\"mean_squared_error\", optimizer=opt, metrics=['mse', 'accuracy'])\n",
    "\n",
    "# save model training checkpoit to this path\n",
    "file_path = './models/model_checkpoint_weights.h5'\n",
    "\n",
    "# use ModelCheckpoint while training to save the best trained version of the model\n",
    "callback_checkpoint = ModelCheckpoint(filepath=file_path,\n",
    "                                      monitor='val_loss',\n",
    "                                      save_best_only=True,\n",
    "                                      save_weights_only=True)\n",
    "\n",
    "#stop the model early if not making big enough progress\n",
    "early_stopping = EarlyStopping(monitor='loss', patience=10, verbose=1)\n",
    "\n",
    "#reduce learning rate if not making big enough progress\n",
    "reduce_lr = ReduceLROnPlateau(monitor='loss', factor=0.3,\n",
    "                              patience=5, min_lr=0.0009)\n",
    "#combine all 3 callbacks\n",
    "callbacks = [early_stopping, callback_checkpoint, reduce_lr]\n",
    "\n",
    "#train the model\n",
    "history = model.fit(train_X, train_y, epochs=100, validation_data=(valid_X, valid_y), callbacks=callbacks, shuffle=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#plot loss and validation loss\n",
    "plt.plot(history.history['loss'], label='train')\n",
    "plt.plot(history.history['val_loss'], label='test')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# load the best model saved by ModelCheckpoint\n",
    "model.load_weights(f'{file_path}')\n",
    "os.remove(file_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict(input_value):\n",
    "\n",
    "    Xt = model.predict(input_value.reshape(1, input_value.shape[0], input_value.shape[1]))\n",
    " \n",
    "    return gdp_scaler.inverse_transform(Xt)[0][0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "#function for saving the model\n",
    "def save_model(model, filepath):\n",
    "    model.save(filepath)\n",
    "    print(f'model saved at {filepath}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "model saved at ./models/lstm-model[1575306167.1460094].h5\n"
     ]
    }
   ],
   "source": [
    "# save model\n",
    "save_model(model, f\"./models/lstm-model[{time.time()}].h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
